
                   Recoded by Evgeny Muchkin 06.10.1998
                  SysOp of PALLY_STATION  tel: 176-74-19

                               (с) STINGER &
                               (с) CYRAX- (*)

                      Руководство по программированию
                              General Sound.

                        Версия v1.04. Редакция 004.

                 1. Краткие технические характеристики GS.
                  --------------------------------------

Процессор: Z80, 12MHz, без циклов wait
ROM      : 32k, 27256
RAM      : Static Ram  128k всего,  112k  доступно для модулей и сэмплов в
           базовой версии
INT      : 37.5 KHz Каналы: 4 независимых 8-и битных канала,  каждый с 6-и
           битным контролем громкости.

             2. Краткое описание GS, или много всякой лабуды.
             ------------------------------------------------

  GS - музыкальная карточка,  предназначенная для проигрывания  музыкальных
модулей и отдельных сэмплов (эффектов).

  Модули для GS - это стандартные Амижные и PCшные 4-х канальные MOD файлы,
а сэмплы - как Амижные signed sample, так и PCшные unsigned sample.

  Проигрыватель MOD  файлов  в  GS  является  практически  полным  аналогом
ProTracker'а на Амиге и создавался при интенсивном  использовании  исходни-
ков ProTracker'a. (Исходники были из Protracker'а v2.1A by Lars "ZAP" Hamre
- Amiga Freelancers)

  MOD Player поддерживает все команды Pro Tracker'а, за исключением двух:

 Е01 Filter On Амига-специфичная команда, включает фильтр высоких частот.

 EFX Invert Loop я еще не видел плейера,  который бы поддерживал эту коман-
ду. Возможно, она поддерживается на каких-то старых плейерах.

  GS представляет из себя,  по-сути,  микропроцессорный комплекс  со  своим
процессором, ПЗУ, ОЗУ и портами, и абсолютно не зависит от главного процес-
сора Спектрума,  что позволяет,  например,  загрузить свой любимый  модуль,
сбросить Спектрум,  загрузить ассемблер и творить под любимую музыку.  Soft
внутри GS полностью берет на себя задачи проигрывания звука,  интерпретации
модуля и т.д.  Программирование GS'а сводится к передаче байт за байтом мо-
дуля и/или сэмплов,  а затем требуется только подавать команды типа: запус-
тить модуль,  установить глобальную громкость проигрывания модуля,   запус-
тить сэмпл #09 в канале #02 и т.д.

  Если предполагается загрузить модуль вместе с сэмплами, то в GENERAL тре-
буется загружать вначале модуль, а затем сэмплы.

  При загрузке модуля очень рекомендуется оставить  свободными  2к  памяти,
т.е. загружать модули длиной максимум 110K. Это условие не является необхо-
димым, но его исполнение очень желательно в целях совместимости с последую-
щими версиями.

  Аналогично очень рекомендуется оставлять по 80 байт для  каждого  сэмпла,
например, если требуется загрузить 63-х килобайтный модуль и 18 сэмплов, то
имеем:

  Total_Sample_Length=112*1024-63*1024-2*1024-18*80=46688 байт

  Это суммарная длина сэмплов, которые при таком положении вещей могут быть
загружены.

  Если же, например, требуется вычислить,  сколько поместится в память GS'а
2-х килобайтных сэмплов, то это вычисляется следующим образом:

 112*1024/(2048+80)=53 сэмпла.

  В GS'е имеются 4 физических канала, которые и проигрывают звук.

  Каналы 0 и 1 - левые, а 2 и 3 - правые.

                        3. Интерфейс со Спектрумом.
                        ---------------------------

  На мир GS смотрит при помощи 4 регистров:

1. Command register - регистр команд,  доступный для записи порт по  адресу
187 (#BB). В этот регистр записываются команды.

2. Status register  -  регистр состояния,  доступный для чтения порт по ад-
ресу 187 (#BB).

  Биты регистра:

   7 - Data bit, флаг данных
   6 - Неопределен
   5 - Неопределен
   4 - Неопределен
   3 - Неопределен
   2 - Неопределен
   1 - Неопределен
   0 - Command bit, флаг команд

  Этот регистр позволяет определить состояние GS, в частности можно ли про-
читать или записать очередной байт данных, или подать очередную команду,  и
т.п.

3. Data register - регистр данных,  доступный для записи порт по адресу 179
(#B3). В этот регистр Спектрум записывает данные, например,  это могут быть
аргументы команд.

4. Output register - регистр вывода,  доступный для чтения порт  по  адресу
179 (#B3). Из этого регистра Спектрум читает данные, идущие от GS.

  Command bit в регистре состояний устанавливается аппаратно  после  записи
команды в регистр команд. Сбрасываться в 0 он может только из GS,  что сиг-
нализирует об определенном этапе исполнения команды.

  Data bit в регистре состояний может быть установлен или  сброшен  как  по
желанию Спектрума,  так и по желанию GS: при записи  Спектрумом  в  регистр
данных он аппаратно устанавливается в 1,  а после чтения GS'ом из этого ре-
гистра сбрасывается в 0. При записи GS в регистр вывода он (все тот же Data
bit) аппаратно устанавливается в 1,  а после чтения из этого порта Спектру-
мом сбрасывается аппаратно в 0.

  Несмотря на то,  что регистр данных и регистр вывода расположены в  прос-
транстве адресов портов по одному и тому же адресу и воздействуют на один и
тот же бит данных,  они являются двумя независимыми регистрами.   Значение,
один раз записанное в один из этих регистров,  остается неизменным в нем до
новой записи.

  Состояние бита данных очень часто неопределено, и если в спецификации ко-
манд не определены значения этого бита на опреденных этапах исполнения  ко-
манды,  недопустимо делать какие-либо предположения  относительно  значения
этого бита.

                           4. Система команд GS.
                           ---------------------

  Вначале позволю себе небольшое отступление от собственно системы  команд.
GS,  как известно,  предназначен в основном для проигрывания модулей и сэм-
плов.  В данной версии (1.03) GS ROM допукается загрузка одного модуля и/и-
ли до 32 сэмплов.

  Каждый сэмпл при загрузке его в память получает свой уникальный идентифи-
катор, который однозначно определяет обращение к данному сэмплу в командах,
которые требуют номер сэмпла.  Самый первый загруженный сэмпл получает  но-
мер (handle) = 1, следующий - номер 2, и т.д.

  То же самое применимо и к модулям,  и этот единственный  загруженный  мо-
дуль будет иметь handle=1 после загрузки.

  Особенностью данной версии является также то,  что вначале требуется заг-
ружать модуль, а затем уже сэмплы.

  Особенности описания команд:

  Команды описываются следующим образом:

 1. Hex код команды
 2. Название команды
 3. Выполняемые действия при исполнении команды
 4. Формат команды
 5. Комментарии к команде

  Формат команды описывается следующим образом:

 GSCOM EQU 187
 GSDAT EQU 179

SC #NN    : Послать код команды в регистр команд

          LD A,#NN
          OUT (GSCOM),A

WC      : Ожидание сброса Command bit

     WCLP IN A,(GSCOM)
          RRCA
          JR C,WCLP

SD Data : Послать данные в регистр данных

          LD A,Data
          OUT (GSDAT),A

WD      : Ожидание  сброса Data bit, по сути, ожидание,  пока GS не примет
          посланные ему данные

     WDLP IN A,(GSCOM)
          RLCA
          JR C,WDLP

GD Data : Принять данные из регистра данных

          IN A,(GSDAT)

WN      : Ожидание  установки Data bit, по сути, ожидание очередных данных
          от GS

     WNLP IN A,(GSCOM)
          RLCA
          JR NC,WNLP


                                Команды GS:

#00 Reset flags
    Сбрасывает флаги Data bit и Command bit.

    SC #00
    WC

    (Data bit=0, Command bit=0)

#01 Set silence (*)
    Выводит в ЦАПы всех каналов #80. По сути устанавливает тишину.

    SC #01
    WC

#02 Set low volume (*)
    Устанавливает громкостx ЦАПов всех каналов в ноль.

    SC #02
    WC

#03 Set high volume (*)
    Устанавливает громкость ЦАПов всех каналов в максимум.

    SC #03
    WC

#04 Set 'E' 3bits (*)
    Устанавливает в 'E' регистре GS 3 младших бита в соответствии с  задан-
    ным значением (2  младших  бита  в  сущности  являются  номером  канала
    #00-#03).

    SD Chan (#00-#07)
    SC #04
    WC

#05 Out volume port (*)
    Устанавливает громкость канала, номер которого содержится в 'E', в ука-
    занное значение. (Команда срабатывает при условии,  что 'E' находится в
    пределах #00-#03)

    SD Volume (#00-#3F)
    SC #05
    WC

#06 Send to DAC (*)
    Выводит байт в ЦАП канала, указываемого по 'E'.

    SD Byte
    SC #06
    WC

#07 Send to DAC and to volume port (*)
    Выводит байт в ЦАП ('E') с заданной громкостью.

    SD Byte
    SC #07
    WC
    SD Volume
    WD

#08 - то же что и команда #00

#09 Sets one's byte volume. (*)
    Установка громкости канала, номер которого задан в 2х старших битах.

    SD Byte (ccvvvvvv)
    SC #09
    WC

    cc - Номер канала
    vvvvvv - Его громкость

#0A DAC output (*)
    Еще один непосредственный вывод в ЦАП.

    SD Byte
    SC #0A
    WC
    SD Chan (#00-#03)
    WD

#0B DAC and Volume output (*)
    И наконец последний вывод в ЦАП с установкой громкости.

    SD Fbyte
    SC #0B
    WC
    SD Sbyte (ccvvvvvv)
    WD

    Назначение битов Sbyte как и у к.#09)

    Команды #01  - #0B служат в основном для построения различных  Covox'ов
    и поигрывателей,  при этом не слишком углубляясь во внутреннюю структу-
    ру GS.

    vvvvvv - Его громкость

#0C DAC output (*)
    Еще один непосредственный вывод в ЦАП.

#0C Call SounDrive Covox mode (*)
    Вызывает режим четырехканального Ковокса,  последовательно копирует ре-
    гистр данных по каналам.  Выход из режима  автоматически  после  вывода
    четвертого байта.

    SD CH1
    SC #0C
    WC
    SD CH2
    WD
    SD CH3
    WD
    SD CH4
    WD

#0D Call Ultravox mode (*)
    Вызывает режим универсального Ковокса,   последовательно  копирует  ре-
    гистр данных по каналам,  число которых регулируется (1-4).В отличие от
    предыдущего варианта синхронизация не производится.  Выход также произ-
    водится автоматически по записи последнего байта.

    SD CHANS
    SC #0D
    WC

    SD CH1
    SD CH2
    SD CH3
    SD CH4

    CHANS (4-е младших бита) указывает какие каналы будут  задействованы  -
    для включения канала соответствующий бит  нужно  установить.Если  канал
    выключен,  то поступивший байт попадает на следующий  включенный  канал
    (если успеет :)


#0E Go to LPT Covox mode
    Переходит в режим одноканального Ковокса,   напрямую  копирует  регистр
    данных в ЦАПы двух (правого и левого) каналов.  Выход из этого режима -
    запись #00 в регистр команд.

    SC #0E
    WC

    SD  \
    SD   \
    ...   Это вывод в ЦАПы
        /
    SD  /

    SC #00
    WC

#0F Go in Profi Covox mode (*)
    Переходит в режим двухканального Ковокса,   напрямую  копирует  регистр
    данных в ЦАПы одного канала,  а регистр каманд в ЦАПы  второго  канала.
    Выход из этого режима - запись #4Е в регистр данных,  затем  последова-
    тельно #0F и #AA в регистр команд.

    SD #59
    SC #0F
    WC

    SD  \
    SC   \
    SD    \
    SC      Это вывод в ЦАПы
    ...   /
    SD   /
    SC  /

    SD #4E
    WD
    SC #0F
    WC
    SC #AA
    WC

#10 Out to any port (*)
    Выводит байт вo внутренний порт GS (#00-#09).

    SD Port
    SC #10
    WC
    SD Data
    WD

#11 In from any port (*)
    читает байт из внутреннего порта GS (#00-#09).

    SD Port
    SC #10
    WC
    GD Data
    WN

#12 OUT to 0 port (*)
    Выводит байт в порт кофигурации GS (#00).

    SD Data
    SC #12
    WC

#13 Jump to Address (*)
    Передает управление по заданному адресу.

    SD ADR.L
    SC #13
    WC
    SD ADR.H
    WD

#14 Load memory block (*)
    Загрузка блока кодов по указанному адресу с заданной длиной.

    SD LEN.L
    SC #14
    SD LEN.H
    WD
    SD ADR.L
    WD
    SD ADR.H

    SD \
    WD  \
    SD   \
    WD     Блок данных длиной LEN
    ...  /
    SD  /
    WD /

#15 Get memory block (*)
    Выгрузка блока кодов по указанному адресу с заданной длиной.

    SD LEN.L
    SC #15
    SD LEN.H
    WD
    SD ADR.L
    WD
    SD ADR.H

    GD \
    WN  \
    GD   \
    WN     Блок данных длиной LEN
    ...  /
    GD  /
    WN /

#16 Poke to address (*)
    Записывает единичный байт по указанному адресу.

    SD ADR.L
    SC #16
    WC
    SD ADR.H
    WD
    SD Byte
    WD

#17 Peek from address (*)
    Считывает единичный байт из указанного адреса.

    SD ADR.L
    SC #17
    WC
    SD ADR.H
    WD
    GD Byte
    WN

#18 Load DE Pair (*)
    Загружает регистовую пару DE (относящуюся к GS,  не путать с  одноимен-
    ной парой Main CPU) указанным словом.

    SD B.E
    SC #18
    WC
    SD B.D
    WD

#19 Poke to (DE) address (*)
    Записывает байт по адресу указанному в DE.

    SD Byte
    SC #19
    WC

#1A Peek from (DE) address (*)
    Считывает содержимое адреса, указываемого по DE.

    SC #1A
    WC
    GD Byte
    WN

#1B Increment of DE Pair (*)
    Увеличивает пару DE на единичку.

    SC #1B
    WC

#1C Poke to (#20XX) address (*)
    Записывает байт по адресу, старший байт которого равен #20.

    SD ADR.L
    SC #1C
    WC
    SD Byte
    WD

#1D Peek from (#20XX) address (*)
    читает байт с адреса, старший байт которого равен #20.

    SD ADR.L
    SC #1D
    WC
    GD Byte
    WN

#1E - #1F Зарезервированы.
#F1 - #F2 Зарезервированы.

#F3 Warm restart
    Сбрасывает полностью GS,  но пропускает  этапы  определения  количества
    страниц памяти и их провеки,  что очень сильно ускоряет процесс инициа-
    лизации.

    SC #F3
    WC

#F4 Cold restart
    Полный перезапуск GS со всеми проверками. По сути, JP #0000.

    SC #F4
    WC

#F5 Busy on
    Устанавливает флаг занятости в #FF

    SC #F5
    WC

#F6 Busy off
    Устанавливает флаг занятости в #00

    SC #F6
    WC

   Изначально Busy=#00.  Исполнение всех команд в GS выполняется в  главном
 цикле командного интерпретатора.  Этот цикл в условном виде можно предста-
 вить так:

 1 if Command bit=0 then go to 1
 2 Execute Command
 3 if Command bit=1 then go to 2
 4 if Playing=0 then go to 1
 5 if Busy=#FF then go to 1
 6 Process Sound
 7 go to 1

  Используя команды Busy можно например инициировать  проигрывание  сэмплов
во всех каналах потом скажем изменить параметры проигрывания  в  каналах  а
потом запустить это все одновременно. Если же их не использовать то возмож-
на такая ситуация: инициируется первый (сэмпл станет проигрываться а только
потом инициируется второй сэмпл и т.д.)

#F7 Get HX Register (*)
    Получить содержимое регистра HX (GS)
    HX участвует в обработке флага Busy.

    SC #F7
    WC
    GD HX
    WN

#F8 - #F9 Зарезервированы.

#FA Out zero_to_zero
    Вывод нуля в нулевой (конфигурационный) порт GS.   Делает  приостановку
    звучания музыки до следующего чтения из к.л. порта.

    SC #FA

    WC

#FB - #FF Зарезервированы.

#20 Get total RAM
    Получить общий объем доступной памяти на GS. (В базовой версии это 112к)

    SC #20
    WC
    GD RAM.L(Младшая часть)
    WN
    GD RAM.M(Средняя часть)
    WN
    GD RAM.H(Старшая часть)

Total RAM=65536*RAM.H+256*RAM.M+RAM.L

#21 Get free RAM
    Получить общий об'ем свободной памяти на GS.

    SC #20
    WC
    GD RAM.L(Младшая часть)
    WN
    GD RAM.M(Средняя часть)
    WN
    GD RAM.H(Старшая часть)

 Free_RAM=65536*RAM.H+256*RAM.M+RAM.L

#23 Get number of RAM Pages
    Получить число страниц на  GS.

    SC #23
    WC
    GD Number_RAM_Pages

    В базовой версии 3 страницы.

#24 - #29 Зарезервированы.

#2A Set Module Master Volume
    Установить громкость проигрывания модулей.

    SD Module_Master_Volume [#00..#40]
    SC #2A
    WC
    [GD Old_Master_Volume] - Старая громк.

    Маленький пример использования данной команды:

    (Предполагается, что играется модуль)

           LD B,#40

     LOOP: LD A,B
           OUT (GSDAT),A
           LD A,#2A
           OUT (GSCOM),A
           EI
           HALT
           DJNZ LOOP

           LD A,#32
           OUT (GSCOM),A

  Вышеописанное плавно снижает громкость играющего модуля, а затем останав-
ливает его.

#2B Set FX Master Volume
    Установить громкость проигрывания эффектов.

    SD FX_Master_Volume [#00..#40]
    SC #2B
    WC
    [GD Old_FX_Volume] - Старая громкость

  Аналогично предыдущей команде, но действует на сэмплы.

  С помощью этих двух команд можно регулировать баланс громкостей модуля  и
сэмплов, и т.п.

#2E Set Current FX
    Установить текущий эффект. Просто присваивает переменной CURFX это зна-
    чение. Если какая-либо команда требует номер сэмпла (sample handle), то
    можно вместо этого номера подать ей #00 и интерпретатор подставит вмес-
    то этого нуля значение переменной CURFX. (См. команды #38, #39, #40-#4F
    для понимания вышеизложенного.)

    SD Cur_FX
    SC #2E
    WC

#30 Load Module
    Загрузка модуля в память.

    SC #30
    WC
   [GD Module_Handle]-номер модуля
   (Command bit=0, Data bit=0)
    SC #D1 (Open Stream-открыть поток)
    WC

    SD \
    WD  \
    ...   Байты модуля
    SD  /
    WD /

    SC #D2 (Close Stream-закрыть поток)
    WC

    Пример:
             LD HL,Mod_adress
             LD DE,0-Mod_length
             LD C,GSCOM

             LD A,#30
             CALL SENDCOM
             LD A,#D1
             CALL SENDCOM

             LD A,(HL)
     LOOP:   IN B,(C)
             JP P,READY
             IN B,(C)
             JP M,LOOP
     READY:  OUT (GSDAT),A
             INC HL
             LD A,(HL)
             INC E
             JP NZ,LOOP
             INC D
             JP NZ,LOOP
     WAIT:   IN B,(C)  ;Ждем принятия
             JP M,WAIT ;последнего байта
             LD A,#D2
             CALL SENDCOM
             IN A,(GSDAT) ; Номер модуля
             OUT (GSDAT),A
             LD A,#31

    SENDCOM: OUT (GSCOM),A
    WAITCOM: IN A,(GSCOM)
             RRCA
             JR C,WAITCOM
             RET

#31 Play module
    Проигрывание модуля.

    SD Module_Handle - номер модуля
    SC #31
    WC

#32 Stop module
    Остановить проигрывание модуля.

    SC #32
    WC

#33 Continue module
    Продолжить проигрывание модуля после остановки.

    SC #33
    WC

#35 Set Module Volume
    Установить громкость проигрывания модулей.

    SD Module_Master_Volume [#00..#40]
    SC #35
    WC
   [GD Old_Master_Volume] - Старая громк.

#36 Data on (*)
    Устанавливает регистр данных в #FF.

    SC #36
    WC
   [GD Data (#FF) ]

#37 Reinitialisation (*)
    Переустанавливает внутренние переменные в исходное состояние.

    SC #37
    WC

#38 Load FX
    Загрузка сэмпла эффекта в память. Загружает беззнаковые сэмплы (PC type)

    SC #38
    WC
   [GD FX_Handle]-номер сэмпла
   (Command bit=0, Data bit=0)
    SC #D1 (Open Stream-открыть поток)
    WC

    SD \
    WD  \
    ...   Байты сэмпла
    SD  /
    WD /

    SC #D2 (Close Stream-закрыть поток)
    WC

  При загрузке каждого сэмпла, в памяти GS создается для этого сэмпла заго-
ловок, в котором описываются различные параметры сэмпла. После загрузки эти
параметры устанавливаются в определенные значения, как то:

  Note=60,    Volume=#40,    FineTune=0,    SeekFirst=#0F,    SeekLast=#0F,
Priority=#80,  No Loop и внутренняя переменная CurFX устанавливается равной
FX_Handle.

  Затем командами #40, #41, #42, #45, #46 и #47 можно эти значения по умол-
чанию сменить на свои.  Это требуется потому что команда #39 для  инициации
проигрывания сэмпла использует значения параметров из заголовка сэмпла.

  В своем естественном виде сэмплы обычно плохо пакуются компрессорами,  но
сжимаемость обычно можно поднять,  если перевести сэмпл в Delta-вид,   т.е.
хранить не абсолютные значения сэмпла,  а  относительное  смещение  относи-
тельно предыдущего байта.  Примерно вот так вот  можно  перевести  сэмпл  в
Delta-вид:

            LD HL,Start_of_sample
            LD DE,0-Length_of_sample
            LD C,#00

      LOOP: LD A,(HL)
            SUB C
            LD C,(HL)
            LD (HL),A
            INC E
            JP NZ,LOOP
            INC D
            JP NZ,LOOP

    А вот как можно закачать сэмпл:

             LD IX,Parameters
             LD HL,Sample_adress
             LD DE,0-Sample_length
             LD C,GSCOM

             LD A,#38
             CALL SENDCOM
             LD A,#D1
             CALL SENDCOM

             LD A,(HL)
     LOOP:   IN B,(C)
             JP P,READY
             IN B,(C)
             JP M,LOOP
     READY:  OUT (GSDAT),A
             INC HL
             ADD A,(HL)
             INC E
             JP NZ,LOOP
             INC D
             JP NZ,LOOP
     WAIT:   IN B,(C)  ;Ждем принятия
             JP M,WAIT ;последнего байта
             LD A,#D2
             CALL SENDCOM

      ; Теперь переопределяем параметры
      ; сэмпла по умолчанию своими
      ; значениями

             LD A,(IX+#00)
             OUT (GSDAT),A  ; Нота
             LD A,#40
             CALL SENDCOM
             LD A,(IX+#01)
             OUT (GSDAT),A  ; Громкость
             LD A,#41

    SENDCOM: OUT (GSCOM), A
    WAITCOM: IN A,(GSCOM)
             RRCA
             JR C,WAITCOM
             RET

#39 Play FX
    Проигрывание эффекта.

    SD FX_Handle - номер сэмпла
    SC #39
    WC

  При исполнении этой команды происходит следующее: смотрятся каналы,  ука-
занные в SeekFirst параметре нашего сэмпла, и если хотя-бы один из них сво-
боден,  в нем и проигрывается сэмпл,  в противном случае смотрятся  каналы,
указанные в SeekLast и если один из них свободен,  в нем и играется  сэмпл,
если свободных нет, то просматриваются все каналы,  указанные SeekLast,  из
них выбирается канал с наименьшим приоритетом и сравнивается с  приоритетом
нашего сэмпла (имеется в виду сэмпл,  который мы хотим проиграть),  если  у
этого сэмпла будет больший приоритет, чем у сэмпла, уже играющего в канале,
то играющий в канале сэмпл будет остановлен,  а наш сэмпл будет  запущен  в
этом канале вместо старого сэмпла. Вот такая вот приоритетная схема...

  Тогда сэмпл запускается в канале, то его нота, громкость и т.п.  парамет-
ры записываются в область данных канала из заголовка сэмпла.

  В общем случае,  что-бы проиграть сэмпл с нужными параметрами,  вы можете
установить эти параметры после загрузки сэмпла и смело использовать  коман-
ду #39. Если же параметры должны меняться, то можно поступать следующим об-
разом: командой #2E сделать текущим требуемый сэмпл,  командами  #4x  изме-
нить его параметры, а затем уже запускать его командой #39.

  Альтернативный метод запуска сэмплов предоставляют команды #80..#9F,  при
исполнении этих команд вы прямо в коде команды указываете,  в каком  канале
требуется запустить сэмпл,  и кроме этого,  вы можете также указать с какой
нотой и/или громкостью требуется запустить сэмпл.

#3A Stop FX in channels
    установка проигрывания эффектов в заданных каналах,  которые указывают-
    ся в маске каналов (Channel Mask).  В ней единица в n-ном  бите  указы-
    вает на то, что эффект в n-ном канале требуется остановить

    SD Channel_Mask
    SC #3A
    WC

  Описанное выше есть идеальный вариант работы данной команды, но к сожале-
нию не все так просто в этом мире, и эта команда действует не так,  а имен-
но: единица в бите 7 останавливает сэмпл в нулевом канале, и т.п. В следую-
щих версиях это будет исправлено,  а пока я могу порекомендовать останавли-
вать вообще все сэмплы маской #FF.

#3D Set FX Volume
    Установить громкость проигрывания эффектов.

    SD FX Volume [#00..#40]
    SC #3D
    WC
   [GD Old_FX_Volume] - Старая громкость

#3E Load FX (Extended version)
    Загрузка сэмпла эффекта в память. Позволяет загружать сэмплы со знаком.
    (Amiga type)

    SD #01 (Signed sample)
    SC #3E
    WC
   [GD FX_Handle]-номер сэмпла
   (Command bit=0, Data bit=0)
    SC #D1 (Open Stream-открыть поток)
    WC

    SD \
    WD  \
    ...   Байты сэмпла
    SD  /
    WD /

    SC #D2 (Close Stream-закрыть поток)
    WC

#40 Set FX Sample Playing Note
    Установка ноты по умолчанию для текущего эффекта.

    SD Note [0..95]
    SC #40
    WC

Note=
 0 C-0
 1 C#0
12 C-1
24 C-2
36 C-3 (C-1 в Амиге)
48 C-4 (C-2 в Амиге)
60 C-5 (C-3 в Амиге)
72 C-6
84 C-7

  В данной версии Sound Generators Wave 2,  3 могут воспроизвести октавы 3,
4 и 5,  поэтому допустимым значением параметра Note является диапазон от 36
до 71.

#41 Set FX Sample Volume
    Установка громкости по умолчанию для текущего эффекта.

    SD FX_Volume [#00..#40]
    SC #41
    WC

#42 Set FX Sample Finetune
    Установка Finetune по умолчанию для текущего эффекта.

    SD FX_Finetune [#00..#40]
    SC #42
    WC

#43 - #44 Зарезервированы.

#45 Set FX Sample Priority
    Установка приоритета для текущего эффекта. (См. команду #39)

    SD FX_Priority [#01..#fe]
    SC #45
    WC

#46 Set FX Sample Seek First parameter
    Установка параметра Seek First для текущего эффекта. (См. команду #39)

    SD FX_SeekFirst
    SC #46
    WC

#47 Set FX Sample Seek Last parameter
    Установка параметра Seek Last для текущего эффекта. (См. команду #39)

    SD FX_SeekLast
    SC #47
    WC

#48 Set FX Sample Loop Begin (*)
    Установка начала цикла для текущего эффекта.

    SD LEN.L
    SC #48
    WC
    SD LEN.M
    WD
    SD LEN.H
    WD

    При равенстве LEN.H - #FF зацикливание не производится

#49 Set FX Sample Loop End (*)
    Установка конца цикла для текущего эффекта.

    SD LEN.L
    SC #49
    WC
    SD LEN.M
    WD
    SD LEN.H
    WD

#4A - #4F Зарезервированы.

#51 - #5F Зарезервированы.

#60 Get Song Position
    Получение значения переменной Song_Position в текущем модуле.

    SC #60
    WC
    GD Song_Position  [#00..#FF]

  Можно интерпретировать как количество проигранных паттернов модуля.  Пос-
ле старта модуля принимает значение 0  и  увеличивается  на  единицу  после
проигрывания очередного паттерна.  Эта переменная может использоваться  для
синхронизирования процессов в Спектруме с проигрыванием модуля.  Для  этого
можно,  например,  в начале процедуры обработки прерывания сделать SC  #60,
затем выполнить процедуры различных операций с экраном,  скроллинга строчек
и т.п. (т.е. чтобы была достаточная для выполнения команды задержка), а за-
тем прочитать значение порта 179 (GD Song_Position),  и сравнить его с тре-
буемым и, в случае равенства, перейти на следующую часть демы, т.е.

  if (Song_Position==My_Position)
  then goto Next_Part_Of_Demo

#61 Get Pattern Position
    Получение значения переменной Pattern_Position в текущем модуле.

    SC #61
    WC
    GD Pattern_Position  [#00..#3F]

  Получить значение смещения в паттерне (текущий ROW), использование - ана-
логично предыдущей команде, однако требуется заметить, что эта величина из-
меняется довольно быстро, и поэтому

 if (Pattern_Position>=My_Position) then goto Next_Part_Of_Demo

#62 Get Mixed Position
    Получить значение Pattern_Position, немного смешанной с Song_Position.

    SC #62
    WC
    GD Mixed_Position

    Mixed_Position: (по битам)

    7-Song_Position.1
    6-Song_Position.0
    5-Pattern_Position.5
    4-Pattern_Position.4
    3-Pattern_Position.3
    2-Pattern_Position.2
    1-Pattern_Position.1
    0-Pattern_Position.0

  Т.е если получить Mixed_Position и сделать с ним AND #3F,   то  получится
вылитый Pattern_Position,  а если после получения его немного RLCA,   RLCA,
AND #02 - то это будут младшие два бита Song_Position. См. примечания к ко-
мандам #60 и #61.

#63 Get Channel Notes
    Получить ноты всех каналов модуля.

    SC #63
    WC
    GD Note_of_channel_0
    WN
    GD Note_of_channel_1
    WN
    GD Note_of_channel_2
    WN
    GD Note_of_channel_3

  Если в каком-либо канале значение ноты изменилось с  последнего  исполне-
ния команды #63, то бит 7 полученного заначения

            Note_of_channel_N

будет в нуле, если же это значение то же самое, что и было раньше,  то этот
бит будет в единице.  Младшие семь битов и есть собственно нота от 0 до 95;
если это значение равно 127,  то это означает,  что никакие сэмплы в канале
не играют. Данная команда предназначена в основном для построения на ее ос-
нове различных анализаторов.

#64 Get Channel Volumes
    Получить громкости всех каналов модуля.

    SC #64
    WC
    GD Volume_of_channel_0
    WN
    GD Volume_of_channel_1
    WN
    GD Volume_of_channel_2
    WN
    GD Volume_of_channel_3

   См. описание команды #63

#65 Jump to position (*)
    Делает переход на заданную позицию.

    SD Position
    SC #65
    WC

#66 Set speed/tempo (*)
    Установка скорости в пределах #01-#1F. При значениях #20-#FF устанавли-
    вается темп проигрывания. Значения темпа соответствуют оригинальным при
    скорости равной #06.

    SD Speed/Tempo
    SC #66
    WC

#67 Get speed value (*)
    Чтение текущей скорости.

    SC #67
    WC
    GD Speed
    WD

#68 Get tempo value (*)
    Чтение текущего темпа.

    SC #68
    WC
    GD Tempo
    WD

#6A - #7F зарезервированы.

#80 Direct Play FX Sample (#80..#83)
    Проигрывание сэмпла в заданном канале.

    SD Sample_Number
    SC #80..#83 (Младшие биты определяют непосредственно номер канала, в
                 котором требуется играть сэмпл) WC

#88 Direct Play FX Sample (#88..#8B)
    Проигрывание сэмпла в заданном канале с заданной нотой.

    SD Sample_Number
    SC #88..#8B (Младшие биты определяют непосредственно номер канала, в
                 котором требуется играть сэмпл) WC SD Note [0..95] WD

#90 Direct Play FX Sample (#90..#93)
    Проигрывание сэмпла в заданном канале с заданной громкостью.

    SD Sample_Number
    SC #90..#93 (Младшие биты определяют непосредственно номер канала, в
                 котором требуется играть сэмпл)
    WC
    SD Volume [#00..#40]
    WD

#98 Direct Play FX Sample (#98..#9B)
    Проигрывание сэмпла в заданном канале с заданной нотой и громкостью.

    SD Sample_Number
    SC #98..#9B (Младшие биты определяют непосредственно номер канала,    в
                 котором требуется играть сэмпл)
    WC
    SD Note [0..95]
    WD
    SD Volume [#00..#40]
    WD

#B0 - #F0 Зарезервированы.

    Примечание: Команды, отмеченные как (*),  являются недокументированными
    и в полной мере относятся только к версии 1.04.   На  работоспособность
    этих команд в последующих версиях автор описания (2) ответственности не
    несет.
    2.Напоминаю, что регистры (их имена), упомянутые в этом описании, отно-
    сятся только и только к внутренним регистрам GS и никакого отношения  к
    регистрам основного процессора не имеют.


                           5. Heмнoгo лиpики...

                         Автopы GS : ( 2 штуки ;)

                          ─── Cлaвa Dangеrous ───
                                 (X-Tradе)

 Eму пpинaдлeжит идeя сoздaния GS'a, aппapaтнaя peaлизaция oнoгo, нeкoтopыe
пoжeлaния oтнoситeльнo Soft'a GS'a,  a тaкжe Amiga 1200,  нa  кoтopoй  мнoю
пpoизвoдились всячeскиe экспepимeнты.  Oн eдинстeнный и нeпoвтopимый пpoиз-
вoдитeль General Sound'a и имeннo oн зaвeдуeт пpoизвoдствoм и пpoдaжeй GS.

                              ─── Stingеr ───

 Этo я,  aвтop сeгo oпусa  и  пo-сoвмeститeльству  душa  и  сepдцe  General
Sound'a.  Я  являюсь  paзpaбoтчикoм  всeгo  встpoeннoгo  Soft'a  в  GS'e  и
пpeдпoлaгaю и дaльшe зaнимaться сим дeйствoм. (Дa,  я тaкжe являюсь aвтopoм
нeкoтopыx xитpыx нaвopoтoв в aппapaтнoй чaсти GS'a,  и был бы  aвтopoм  eщe
мнoгиx,  eсли бы нe был всe вpeмя сдepживaeм Cлaвoй,  пoстoяннo oзaбoчeнным
пpoблeмaми пoнижeния цeны. )

 Haписaв oкoлo 20 кб кoдa зa пoл-гoдa,  пpизaнaться,  я нeмнoгo устaл,   нo
имeю дoвoльнo бoльшиe плaны oтнoситeльнo слeдующиx вepсий GS'a, кaк-тo:

 - Wave 4 Sound Generators вoспpoизвoдящиx всe oктaвы.
 - Ускopeниe зa счeт oныx пpoцeнтoв нa 30-40 гeнepaции звукa.
 - Oчeнь xoтeлoсь бы пpoигpывaниe STM'oв oт PC.
 - Paзвитaя систeмa кoмaнд.
 - Paзличныe  спeцэффeкты  нaд  сэмплaми
 - Xpaнeниe пaттepнoв в  зaкoмпpeссoвaннoм  видe  (oстaeтся  oкoлo  15%  oт
   изнaчaльнoгo oбьeмa).
 - И мнoгoe дpугoe

 Bсe пpoгpaммнoe oбeспeчeниe  дoлжнo  paбoтaть  и  нa  пoслeдующиx  вepсияx
пpoшивки,   eсли  oнo  нaписaнo  в  сooтвeтствии  с  мoими  вышeизлoжeнными
пoжeлaниями и тpeбoвaниями.  Кpoмe oписaнныx кoмaнд в GS'e  сущeствуeт  eщe
бoльшoe кoличeствo кoмaнд,  кoтopыe нe дoкумeнтиpoвaны,  и  я  oстaвляю  зa
сoбoй  пpaвo  измeнять  иx  кaким-угoднo  oбpaзoм  и  тoлькo   oтнoситeльнo
дoкумeнтиpoвaныx кoмaнд пpиeмлю зaкoнныe пpeтeнзии  типa:  "B  дoкумeнтaции
нaписaнo тaк, a в пpoшивкe этo paбoтaeт пo дpугoму... "

 Я плaниpую знaчитeльнoe paсшиpeниe систeмы кoмaнд, и буду paд кoнстpуктив-
ным (жeлaтeльнo кoнкpeтным) пpeдлoжeниям.

Taк чтo, eсли вы oзвучивaeтe игpушку или пишeтe музыкaльный peдaктop для GS
и oбнapуживaeтe,  чтo вaм oчeнь нe xвaтaeт кaкoй-либo кoмaнды,  тo  звoнитe
мнe и выскaзывaйтe пpeдлoжeния. (Teлeфoн, я думaю,  oсoбoгo тpудa узнaть нe
сoстaвит ;)

                           Sanx 4 moral support:
                              Димa (X-Trade)
                               SParker (XLD)
                 _________________________________________

                               -= THE END =-

